const BaseWidget = require('../../core/BaseWidget');
const path = require('path');
const CalendarDatabase = require('./database');

class CalendarWidget extends BaseWidget {
    static displayName = 'Calendar';
    static icon = 'fa-calendar-alt';
    static description = 'Manage events and appointments';
    
    constructor(id, config = {}) {
        super(id, config);
        this.events = [];
        this.currentDate = new Date();
        this.loadI18n();
    }

    async loadI18n() {
        try {
            const lang = this.config.language || 'en';
            const i18nPath = path.join(__dirname, 'locales', `${lang}.json`);
            delete require.cache[require.resolve(i18nPath)];
            this.i18n = require(i18nPath);
        } catch (error) {
            // Fallback to English
            const i18nPath = path.join(__dirname, 'locales', 'en.json');
            delete require.cache[require.resolve(i18nPath)];
            this.i18n = require(i18nPath);
        }
    }

    getName() {
        return 'CalendarWidget';
    }

    getVersion() {
        return '1.0.0';
    }

    getDescription() {
        return this.i18n.description;
    }

    async initialize() {
        // Load events from database
        const dbManager = this.getDatabaseManager();
        if (dbManager) {
            const calendarDb = dbManager.getWidgetDatabase('calendar');
            if (calendarDb) {
                this.events = await calendarDb.getEvents(this.id);
            }
        }
    }

    async addEvent(title, date, type = 'meeting', description = '') {
        const dbManager = this.getDatabaseManager();
        if (dbManager) {
            const calendarDb = dbManager.getWidgetDatabase('calendar');
            if (calendarDb) {
                const event = await calendarDb.addEvent(this.id, title, date, type, description);
                this.events.push(event);
                return event;
            }
        }
        
        // Fallback to in-memory storage
        const event = {
            id: Date.now().toString(),
            title,
            date,
            type,
            description,
            createdAt: new Date().toISOString()
        };
        this.events.push(event);
        this.updateData({ events: this.events });
        return event;
    }

    async deleteEvent(id) {
        const dbManager = this.getDatabaseManager();
        if (dbManager) {
            const calendarDb = dbManager.getWidgetDatabase('calendar');
            if (calendarDb) {
                const result = await calendarDb.deleteEvent(id);
                if (result) {
                    // Update local events array
                    this.events = this.events.filter(e => e.id !== id);
                }
                return result;
            }
        }
        
        // Fallback to in-memory storage
        const index = this.events.findIndex(e => e.id === id);
        if (index > -1) {
            this.events.splice(index, 1);
            this.updateData({ events: this.events });
            return true;
        }
        return false;
    }

    getEventsForDate(date) {
        return this.events.filter(event => {
            const eventDate = new Date(event.date);
            return eventDate.toDateString() === date.toDateString();
        });
    }

    getUpcomingEvents(days = 7) {
        const now = new Date();
        const future = new Date(now.getTime() + days * 24 * 60 * 60 * 1000);
        return this.events.filter(event => {
            const eventDate = new Date(event.date);
            return eventDate >= now && eventDate <= future;
        }).sort((a, b) => new Date(a.date) - new Date(b.date));
    }

    changeView(direction) {
        if (direction === 'prev') {
            this.currentDate.setMonth(this.currentDate.getMonth() - 1);
        } else if (direction === 'next') {
            this.currentDate.setMonth(this.currentDate.getMonth() + 1);
        }
    }

    render() {
        const monthName = this.currentDate.toLocaleDateString(this.config.language || 'en', { 
            month: 'long', 
            year: 'numeric' 
        });
        
        const upcomingEvents = this.getUpcomingEvents();
        
        return `
            <div class="calendar-widget" data-widget-id="${this.id}">
                <div class="calendar-header">
                    <h3>${this.i18n.title}</h3>
                    <div class="calendar-controls">
                        <button onclick="window.widgetManager.executeWidgetAction('${this.id}', 'changeView', { direction: 'prev' })">
                            <i class="fas fa-chevron-left"></i>
                        </button>
                        <span id="calendar-current-date-${this.id}">${monthName}</span>
                        <button onclick="window.widgetManager.executeWidgetAction('${this.id}', 'changeView', { direction: 'next' })">
                            <i class="fas fa-chevron-right"></i>
                        </button>
                        <button onclick="window.widgetManager.executeWidgetAction('${this.id}', 'showAddEventModal', {})" class="add-event-btn" title="Add Event">
                            <i class="fas fa-plus"></i>
                        </button>
                    </div>
                </div>
                <div class="calendar-view" id="calendar-view-${this.id}">
                    ${this.renderMiniCalendar()}
                </div>
                <div class="calendar-events">
                    <h4>${this.i18n.upcomingEvents}</h4>
                    <div id="events-list-${this.id}">
                        ${upcomingEvents.map(event => this.renderEventItem(event)).join('')}
                    </div>
                </div>
            </div>
            ${this.renderAddEventModal()}
        `;
    }

    renderMiniCalendar() {
        const year = this.currentDate.getFullYear();
        const month = this.currentDate.getMonth();
        const firstDay = new Date(year, month, 1);
        const lastDay = new Date(year, month + 1, 0);
        
        // Get the first day of the calendar (Monday of the week that includes the first day)
        const startDate = new Date(firstDay);
        const firstDayOfWeek = firstDay.getDay(); // 0 = Sunday, 1 = Monday, etc.
        // Adjust to start from Monday (1) instead of Sunday (0)
        const offset = firstDayOfWeek === 0 ? -6 : 1 - firstDayOfWeek;
        startDate.setDate(startDate.getDate() + offset);
        
        const daysOfWeek = this.i18n.daysOfWeek;
        let html = '<div class="mini-calendar">';
        
        // Header with days of week
        html += '<div class="calendar-weekdays">';
        for (const day of daysOfWeek) {
            html += `<div class="weekday">${day}</div>`;
        }
        html += '</div>';
        
        // Calendar days
        html += '<div class="calendar-days">';
        const today = new Date();
        
        for (let i = 0; i < 42; i++) {
            const date = new Date(startDate);
            date.setDate(startDate.getDate() + i);
            
            const isCurrentMonth = date.getMonth() === month;
            const isToday = date.toDateString() === today.toDateString();
            const hasEvents = this.getEventsForDate(date).length > 0;
            
            html += `<div class="calendar-day ${isCurrentMonth ? 'current-month' : 'other-month'} ${isToday ? 'today' : ''}" 
                         data-date="${date.toISOString().split('T')[0]}">
                        ${date.getDate()}
                        ${hasEvents ? '<div class="event-indicator"></div>' : ''}
                    </div>`;
        }
        html += '</div></div>';
        
        return html;
    }

    renderEventItem(event) {
        const eventDate = new Date(event.date);
        const dateStr = eventDate.toLocaleDateString(this.config.language || 'en', {
            month: 'short',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit'
        });
        
        return `
            <div class="event-item" data-event-id="${event.id}">
                <div class="event-title">${event.title}</div>
                <div class="event-date">${dateStr}</div>
                <span class="event-type ${event.type}">${this.i18n.eventTypes[event.type]}</span>
                <button class="delete-event-btn" onclick="window.widgetManager.executeWidgetAction('${this.id}', 'deleteEvent', { eventId: '${event.id}' })" title="Delete Event">
                    <i class="fas fa-trash"></i>
                </button>
            </div>
        `;
    }

    renderAddEventModal() {
        return `
            <div class="add-event-modal" id="add-event-modal-${this.id}" style="display: none;">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3>${this.i18n.addEventModal.title}</h3>
                        <button class="close-btn" onclick="window.widgetManager.executeWidgetAction('${this.id}', 'hideAddEventModal', {})">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                    <div class="modal-body">
                        <form id="add-event-form-${this.id}" onsubmit="window.widgetManager.executeWidgetAction('${this.id}', 'handleAddEvent', { event: event, widgetId: '${this.id}' }); return false;">
                            <div class="form-group">
                                <label>${this.i18n.addEventModal.titleLabel}</label>
                                <input type="text" id="event-title-${this.id}" required 
                                       placeholder="${this.i18n.addEventModal.titlePlaceholder}">
                            </div>
                            <div class="form-group">
                                <label>${this.i18n.addEventModal.dateLabel}</label>
                                <input type="datetime-local" id="event-date-${this.id}" required>
                            </div>
                            <div class="form-group">
                                <label>${this.i18n.addEventModal.typeLabel}</label>
                                <select id="event-type-${this.id}">
                                    <option value="meeting">${this.i18n.eventTypes.meeting}</option>
                                    <option value="reminder">${this.i18n.eventTypes.reminder}</option>
                                    <option value="deadline">${this.i18n.eventTypes.deadline}</option>
                                </select>
                            </div>
                            <div class="form-group">
                                <label>${this.i18n.addEventModal.descriptionLabel}</label>
                                <textarea id="event-description-${this.id}" rows="3"
                                          placeholder="${this.i18n.addEventModal.descriptionPlaceholder}"></textarea>
                            </div>
                            <div class="form-actions">
                                <button type="submit" class="submit-btn">
                                    <i class="fas fa-plus"></i> ${this.i18n.addEventModal.addButton}
                                </button>
                                <button type="button" class="cancel-btn" onclick="window.widgetManager.executeWidgetAction('${this.id}', 'hideAddEventModal', {})">
                                    ${this.i18n.addEventModal.cancelButton}
                                </button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        `;
    }

    destroy() {
        // Cleanup if needed
        super.destroy();
    }

    // Internal action handlers
    async showAddEventModal() {
        const modal = document.getElementById(`add-event-modal-${this.id}`);
        if (modal) {
            modal.style.display = 'block';
            // Set default date to current datetime
            const dateInput = document.getElementById(`event-date-${this.id}`);
            if (dateInput) {
                const now = new Date();
                const localDateTime = new Date(now.getTime() - now.getTimezoneOffset() * 60000)
                    .toISOString()
                    .slice(0, 16);
                dateInput.value = localDateTime;
            }
        }
    }

    hideAddEventModal() {
        const modal = document.getElementById(`add-event-modal-${this.id}`);
        if (modal) {
            modal.style.display = 'none';
            const form = document.getElementById(`add-event-form-${this.id}`);
            if (form) {
                form.reset();
            }
        }
    }

    async handleAddEvent(params) {
        const { event, widgetId } = params;
        event.preventDefault();
        
        const title = document.getElementById(`event-title-${this.id}`).value;
        const date = document.getElementById(`event-date-${this.id}`).value;
        const type = document.getElementById(`event-type-${this.id}`).value;
        const description = document.getElementById(`event-description-${this.id}`).value;
        
        try {
            await this.addEvent(title, new Date(date).toISOString(), type, description);
            this.hideAddEventModal();
            this.refreshWidget();
        } catch (error) {
            console.error('Error adding event:', error);
            alert('Error adding event');
        }
    }

    async deleteEventFromWidget(params) {
        const { eventId } = params;
        if (!confirm('Are you sure you want to delete this event?')) {
            return;
        }
        
        try {
            await this.deleteEvent(eventId);
            this.refreshWidget();
        } catch (error) {
            console.error('Error deleting event:', error);
            alert('Error deleting event');
        }
    }

    refreshWidget() {
        // Refresh the widget by updating its content
        const widgetContent = document.getElementById(`widget-content-${this.id}`);
        if (widgetContent) {
            widgetContent.innerHTML = this.render();
        }
    }
}

module.exports = CalendarWidget;